/*
 * Contacts.java
 *
 *  This program displays records from an SQL Server 2005 Database
 *  using a Disconnected RowSet object. The aplication connects to a
 *  table Contacts in a database named AddressBook.
 *
 *  Copyright (c) 2006 Aptech Software Limited. All Rights Reserved.
 */

package demo.jdbc;

import com.sun.rowset.CachedRowSetImpl;
import java.awt.HeadlessException;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import javax.sql.rowset.spi.SyncProviderException;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 * This program uses a CachedRowSet object to display, update and insert
 * records from an Address Book.
 * @author  vincent
 */
public class Contacts extends javax.swing.JFrame {
    
    /** Creates new form Contacts */
    public Contacts() {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows." +
                    "WindowsLookAndFeel");
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        }
        UIManager.put("Button.showMnemonics", Boolean.TRUE);
//        getContentPane().setBackground(new Color(212,208,200));
        
        try {
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            connection = java.sql.DriverManager.getConnection(getConnectionUrl(),
                    userName, password);
            
            if(connection != null) {
                System.out.println("Connection Successful!!");
            }
            
            rowSet = new CachedRowSetImpl();
            rowSet.setUsername(userName);
            rowSet.setPassword(password);
            rowSet.setUrl(getConnectionUrl());
            rowSet.setCommand("Select * from Contacts");
            int[] keys = {1};
            rowSet.setKeyColumns(keys);
            rowSet.execute(connection);
            
        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        initComponents();
        try {
            // Displaying the initial record
            rowSet.next();
            txtFirstName.setText(rowSet.getString("FirstName"));
            txtLastName.setText(rowSet.getString("LastName"));
            txaAddress.setText(rowSet.getString("Address"));
            txtPhone.setText(rowSet.getString("Phone"));
            txfBirth.setText((rowSet.getDate("BirthDate").toString()));
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    
    /**
     * This method returns the URL for the SQL Server 2005 database.
     * @return The string contaning the URL, server name, instance name
     * and database name.
     */
    private String getConnectionUrl() {
        return url + serverName + ";instanceName=" + instanceName +
                ";databaseName="+ databaseName;
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblHeader = new javax.swing.JLabel();
        pnlContacts = new javax.swing.JPanel();
        lblFirstName = new javax.swing.JLabel();
        txtFirstName = new javax.swing.JTextField();
        lblLastName = new javax.swing.JLabel();
        txtLastName = new javax.swing.JTextField();
        lblAddress = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txaAddress = new javax.swing.JTextArea();
        lblPhone = new javax.swing.JLabel();
        txtPhone = new javax.swing.JTextField();
        lblBirthDate = new javax.swing.JLabel();
        txfBirth = new JFormattedTextField(new SimpleDateFormat("yyyy-mm-dd"));
        txfBirth.setValue(new java.sql.Date(time));
        txfBirth.setText("");
        btnPrevious = new javax.swing.JButton();
        btnNext = new javax.swing.JButton();
        lblDateFormat = new javax.swing.JLabel();
        pnlControl = new javax.swing.JPanel();
        btnNewContact = new javax.swing.JButton();
        btnSave = new javax.swing.JButton();
        btnEdit = new javax.swing.JButton();
        btnConfirm = new javax.swing.JButton();
        btnExit = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Contacts Diary");
        getContentPane().setLayout(null);

        lblHeader.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
        lblHeader.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblHeader.setText("My Address Book");
        lblHeader.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        lblHeader.setFocusable(false);
        lblHeader.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        lblHeader.setPreferredSize(new java.awt.Dimension(250, 30));
        getContentPane().add(lblHeader);
        lblHeader.setBounds(10, 10, 317, 30);

        pnlContacts.setBorder(javax.swing.BorderFactory.createTitledBorder("Contact Details"));
        pnlContacts.setLayout(null);

        lblFirstName.setText("First Name:");
        lblFirstName.setPreferredSize(new java.awt.Dimension(53, 20));
        pnlContacts.add(lblFirstName);
        lblFirstName.setBounds(10, 50, 60, 14);

        txtFirstName.setEditable(false);
        txtFirstName.setPreferredSize(new java.awt.Dimension(180, 20));
        pnlContacts.add(txtFirstName);
        txtFirstName.setBounds(80, 50, 180, 20);

        lblLastName.setText("Last Name:");
        lblLastName.setPreferredSize(new java.awt.Dimension(31, 20));
        pnlContacts.add(lblLastName);
        lblLastName.setBounds(10, 80, 60, 20);

        txtLastName.setEditable(false);
        pnlContacts.add(txtLastName);
        txtLastName.setBounds(80, 80, 180, 20);

        lblAddress.setText("Address:");
        lblAddress.setPreferredSize(new java.awt.Dimension(45, 20));
        pnlContacts.add(lblAddress);
        lblAddress.setBounds(10, 110, 45, 20);

        txaAddress.setEditable(false);
        txaAddress.setColumns(20);
        txaAddress.setFont(new java.awt.Font("Tahoma", 0, 11)); // NOI18N
        txaAddress.setLineWrap(true);
        txaAddress.setRows(5);
        jScrollPane1.setViewportView(txaAddress);

        pnlContacts.add(jScrollPane1);
        jScrollPane1.setBounds(80, 110, 164, 110);

        lblPhone.setText("Phone:");
        lblPhone.setPreferredSize(new java.awt.Dimension(34, 20));
        pnlContacts.add(lblPhone);
        lblPhone.setBounds(20, 230, 34, 20);

        txtPhone.setEditable(false);
        txtPhone.setPreferredSize(new java.awt.Dimension(180, 20));
        pnlContacts.add(txtPhone);
        txtPhone.setBounds(80, 230, 180, 20);

        lblBirthDate.setText("Birth Date:");
        lblBirthDate.setPreferredSize(new java.awt.Dimension(50, 20));
        pnlContacts.add(lblBirthDate);
        lblBirthDate.setBounds(10, 260, 50, 14);

        txfBirth.setEditable(false);
        pnlContacts.add(txfBirth);
        txfBirth.setBounds(80, 260, 130, 20);

        btnPrevious.setText("Previous");
        btnPrevious.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPreviousActionPerformed(evt);
            }
        });
        pnlContacts.add(btnPrevious);
        btnPrevious.setBounds(10, 300, 80, 23);

        btnNext.setText("Next");
        btnNext.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNextActionPerformed(evt);
            }
        });
        pnlContacts.add(btnNext);
        btnNext.setBounds(250, 300, 55, 23);

        lblDateFormat.setText("(YYYY-MM-DD)");
        pnlContacts.add(lblDateFormat);
        lblDateFormat.setBounds(220, 260, 70, 14);

        getContentPane().add(pnlContacts);
        pnlContacts.setBounds(10, 50, 320, 330);

        pnlControl.setBorder(javax.swing.BorderFactory.createTitledBorder("Options"));
        pnlControl.setLayout(null);

        btnNewContact.setText("New Contact");
        btnNewContact.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNewContactActionPerformed(evt);
            }
        });
        pnlControl.add(btnNewContact);
        btnNewContact.setBounds(10, 20, 100, 23);

        btnSave.setText("Save");
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });
        pnlControl.add(btnSave);
        btnSave.setBounds(250, 20, 57, 23);

        btnEdit.setText("Edit Contact");
        btnEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnEditActionPerformed(evt);
            }
        });
        pnlControl.add(btnEdit);
        btnEdit.setBounds(130, 20, 100, 23);

        btnConfirm.setText("Confirm Changes");
        btnConfirm.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnConfirmActionPerformed(evt);
            }
        });
        pnlControl.add(btnConfirm);
        btnConfirm.setBounds(110, 60, 130, 23);

        getContentPane().add(pnlControl);
        pnlControl.setBounds(10, 390, 320, 90);

        btnExit.setText("Exit");
        btnExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnExitActionPerformed(evt);
            }
        });
        getContentPane().add(btnExit);
        btnExit.setBounds(260, 490, 60, 23);

        setSize(new java.awt.Dimension(347, 552));
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents
    
    /**
     * This method is invoked to exit the application and to close all the JDBC
     * resources.
     * @param evt ActionEvent object to store information about the click on the
     * Exit button.
     */
    private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExitActionPerformed
        try {
// TODO add your handling code here:
            connection.commit();
            connection.close();
            rowSet.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        System.exit(0);
    }//GEN-LAST:event_btnExitActionPerformed
    
    /**
     * This method is invoked to write back all the changes made to the contacts
     * back to the address book.
     * @param evt ActionEvent object to store information about the click on the
     * Confirm Changes button.
     */
    private void btnConfirmActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConfirmActionPerformed
// TODO add your handling code here:
        String title = "Save to Database";
        String message = "Do you want to save the changes to the database?";
        int option = JOptionPane.showConfirmDialog(this, message, title,
                JOptionPane.YES_NO_CANCEL_OPTION);
        if(option == JOptionPane.YES_OPTION) {
            try {
                rowSet.acceptChanges(connection);
            } catch (SyncProviderException ex) {
                ex.printStackTrace();
            }
        } else {
            return;
        }
    }//GEN-LAST:event_btnConfirmActionPerformed
    
    /**
     * This method is invoked to either save new contact information or to
     * update an existing contact in the address book.
     * @param evt ActionEvent object to store information about the click on the
     * Save button.
     */
    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
// TODO add your handling code here:
        // Check if all contact information has been entered.
        if((txtFirstName.getText() != null) && (txtLastName.getText() != null)
        && (txaAddress.getText() != null) && (txfBirth.getText()!= null) &&
                (txtPhone.getText() != null)) {
            if(editFlag){
                // Editing Existing contact information
                try {
                    rowSet.updateString("FirstName", txtFirstName.getText().trim());
                    rowSet.updateString("LastName", txtLastName.getText().trim());
                    rowSet.updateString("Address", txaAddress.getText().trim());
                    rowSet.updateString("Phone",txtPhone.getText().trim());
                    if(txfBirth.isEditValid()){
                        java.sql.Date d =
                                java.sql.Date.valueOf(txfBirth.getText().trim());
                        rowSet.updateDate("BirthDate", d);
                    }
                    rowSet.updateRow();
                } catch (NumberFormatException ex) {
                    ex.printStackTrace();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            } else {
                try {
                    // Insert new contact information
                    rowSet.moveToInsertRow();
                    rowSet.updateString("FirstName", txtFirstName.getText().trim());
                    rowSet.updateString("LastName", txtLastName.getText().trim());
                    rowSet.updateString("Address", txaAddress.getText().trim());
                    rowSet.updateString("Phone", txtPhone.getText().trim());
                    if(txfBirth.isEditValid()){
                        java.sql.Date d =
                                java.sql.Date.valueOf(txfBirth.getText().trim());
                        rowSet.updateDate("BirthDate", d);
                    } else {
                        String message = "Please enter the date in YYYY-MM-DD" +
                                " format.";
                        String title = "Error";
                        JOptionPane.showMessageDialog(this, message, title,
                                JOptionPane.ERROR_MESSAGE);
                    }
                    rowSet.insertRow();
                    rowSet.moveToCurrentRow();
                    System.out.println("Row Inserted!");
                } catch (HeadlessException ex) {
                    ex.printStackTrace();
                } catch (NumberFormatException ex) {
                    ex.printStackTrace();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        } else {
            // Display an error message.
            String message = "Unable to insert blank contact.!";
            String title = "Error";
            JOptionPane.showMessageDialog(this, message, title,
                    JOptionPane.ERROR_MESSAGE);
        }
    }//GEN-LAST:event_btnSaveActionPerformed
    
    /**
     * This method is invoked to edit an existing contact from the address book.
     * @param evt ActionEvent object to store information about the click on the
     * Edit Contact button.
     */
    private void btnEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEditActionPerformed
// TODO add your handling code here:
        editFlag = true;
        txtFirstName.setEditable(true);
        txtLastName.setEditable(true);
        txaAddress.setEditable(true);
        txtPhone.setEditable(true);
        txfBirth.setEditable(true);
        txtFirstName.grabFocus();
    }//GEN-LAST:event_btnEditActionPerformed
    
    /**
     * This method is invoked when a new contact is to be inserted in the
     * address book. The method makes all contact fields blank and editable.
     * @param evt ActionEvent object to store information about the click on the
     * New Contact button.
     */
    private void btnNewContactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNewContactActionPerformed
// TODO add your handling code here:
        editFlag = false;
        txtFirstName.setEditable(true);
        txtLastName.setEditable(true);
        txaAddress.setEditable(true);
        txtPhone.setEditable(true);
        txfBirth.setEditable(true);
        txtFirstName.grabFocus();
        txtFirstName.setText("");
        txtLastName.setText("");
        txaAddress.setText("");
        txtPhone.setText("");
        txfBirth.setText("");
    }//GEN-LAST:event_btnNewContactActionPerformed
    
    /**
     * This method is invoked to display the next contact from the address book.
     * When the last contact is being displayed, the Next button is disabled.
     * @param evt ActionEvent object to store information about the click on the
     * Next button.
     */
    private void btnNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNextActionPerformed
        // TODO add your handling code here:
        try {
            rowSet.next();
            if(rowSet.isAfterLast()){
                btnNext.setEnabled(false);
            } else {
                txtFirstName.setText(rowSet.getString("FirstName"));
                txtLastName.setText(rowSet.getString("LastName"));
                txaAddress.setText(rowSet.getString("Address"));
                txtPhone.setText(rowSet.getString("Phone"));
                txfBirth.setText((rowSet.getDate("BirthDate").toString()));
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        btnPrevious.setEnabled(true);
    }//GEN-LAST:event_btnNextActionPerformed
    
    /**
     * This method is invoked to display the previous contact from the address
     * book.
     * When the first contact is being displayed, the previous button is
     * disabled.
     * @param evt ActionEvent object to store information about the click on the
     * Previous button.
     */
    private void btnPreviousActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPreviousActionPerformed
// TODO add your handling code here:
        try {
            rowSet.previous();
            if(rowSet.isBeforeFirst()){
                btnPrevious.setEnabled(false);
            } else {
                txtFirstName.setText(rowSet.getString("FirstName"));
                txtLastName.setText(rowSet.getString("LastName"));
                txaAddress.setText(rowSet.getString("Address"));
                txtPhone.setText(rowSet.getString("Phone"));
                txfBirth.setText((rowSet.getDate("BirthDate").toString()));
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        btnNext.setEnabled(true);
    }//GEN-LAST:event_btnPreviousActionPerformed
    
    
    /**
     * This is the entry point for the AddressBook application.
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Contacts().setVisible(true);
            }
        });
    }
    
    /**
     * Variable to store a reference to a Connection object.
     */
    private java.sql.Connection connection = null;
    /**
     * Variable to store the URL connection string.
     */
    private final String url = "jdbc:sqlserver://";
    /**
     * Variable to store the IP address of the machine on which SQL Server 2005
     * database is located.
     */
    private final String serverName = "localhost";
    /**
     * Variable to store the default port number of SQL Server Database.
     */
    private final String portNumber = "1433";
    /**
     * Variable to store the instance name of the SQL Server.
     */
    private final String instanceName = "SQLEXPRESS";
    /**
     * Variable to store the name of the database to connect to.
     */
    private final String databaseName = "ContactManager";
    /**
     * Variable to store the user name to connect to SQL Server.
     */
    private final String userName = "sa";
    /**
     * Variable to store the pasword to connect to SQL Server.
     */
    private final String password = "admin@123";
    /**
     * Statement object to hold a reference to the Statement object.
     */
    private Statement stBook = null;
    /**
     * Variable name to store the number of seconds for calculating the date.
     */
    private long time;
    /**
     * Variable to indicate whether an existing record is being edited or a new
     * record is being added to the database.
     */
    private boolean editFlag = false;
    /**
     * Variable to store a reference to a disconnected CachedRowSet
     */
    private CachedRowSetImpl rowSet = null;
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnConfirm;
    private javax.swing.JButton btnEdit;
    private javax.swing.JButton btnExit;
    private javax.swing.JButton btnNewContact;
    private javax.swing.JButton btnNext;
    private javax.swing.JButton btnPrevious;
    private javax.swing.JButton btnSave;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblAddress;
    private javax.swing.JLabel lblBirthDate;
    private javax.swing.JLabel lblDateFormat;
    private javax.swing.JLabel lblFirstName;
    private javax.swing.JLabel lblHeader;
    private javax.swing.JLabel lblLastName;
    private javax.swing.JLabel lblPhone;
    private javax.swing.JPanel pnlContacts;
    private javax.swing.JPanel pnlControl;
    private javax.swing.JTextArea txaAddress;
    private javax.swing.JFormattedTextField txfBirth;
    private javax.swing.JTextField txtFirstName;
    private javax.swing.JTextField txtLastName;
    private javax.swing.JTextField txtPhone;
    // End of variables declaration//GEN-END:variables
}
